package org.redswallow.filter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import org.redswallow.filter.dispatch.PluginInvokerImpl;
import org.redswallow.filter.plugin.Plugin;
import org.redswallow.log.LogFactory;
import org.redswallow.util.ParameterRequestWrapper;
import org.redswallow.util.Utils;
import org.redswallow.util.config.ConfigConstants;
import org.redswallow.util.config.IPropertySet;
import org.redswallow.util.config.MappedPropertySet;
import org.slf4j.Logger;


public class RedSwallowFilter implements Filter {

	private Logger log = LogFactory.getLog(RedSwallowFilter.class);
	
	private String charset;
	
	public void destroy() {
		
		RedSwallowContext.getInstance(null).
				getPluginInvoker().shutdown();
		
		log.debug("RedSwallowFilter destroy ...");
	}

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		
		if (!(request instanceof HttpServletRequest)) {
			log.debug("request is not HttpServletRequest");
			chain.doFilter(request, response);
			return;
		}
		
		if (request.getCharacterEncoding()==null)
			request.setCharacterEncoding(charset);
		
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		
		log.debug("uri:{}", httpRequest.getRequestURI()+", charset:"+request.getCharacterEncoding());
		log.debug(Utils.printMap(httpRequest.getParameterMap()));
		
		///////////////////////////////////////////
		ParameterRequestWrapper paramRequest = new ParameterRequestWrapper(httpRequest, request.getParameterMap());
		
		
		if (!RedSwallowContext.getInstance(null).
				getPluginInvoker().invoke(paramRequest, response))
			return;
		
		log.debug(Utils.printMap(paramRequest.getParameterMap()));
		
		chain.doFilter(paramRequest, response);
	}

	public void init(FilterConfig filterConfig) throws ServletException {
		
		RedSwallowContext context = RedSwallowContext.getInstance(filterConfig);
		
		Plugin[] plugins = new PluginFactory().createPlugins();
		IPropertySet filterRule = new MappedPropertySet(ConfigConstants.REDSWALLOW_XSSCHECKER+ConfigConstants.CONFIG_RULE, context.getPropertySet());
		context.setPluginInvoker(new PluginInvokerImpl(plugins, filterRule));
		
		charset = context.getPropertySet().getString(ConfigConstants.REDSWALLOW_XSSCHECKER+ConfigConstants.CHARSET, "UTF-8");
		log.debug("RedSwallowFilter default charset(UTF-8):"+charset);
		
		if (Utils.isBlank(charset)) charset="UTF-8";
		
		context.getPluginInvoker().initialize();
		
		log.debug("RedSwallowFilter has initialized.");
		
		filterConfig.getServletContext().log("RedSwallowFilter has initialized.");
	}

}
